import {
  cloneDeep,
  isSuccessReqBackend,
  getBackendDataItems,
  treeTools
} from "@gd-accbuild-core/config/utils";
import { globalConfig } from "@gd-accbuild-core/config";
import { computed, watch, inject, reactive } from "vue";
/* 更具不同类型表格/表单 设置options */
const getSelectOptions = ({
  staticConfig,
  resOptions,
  paramKeys = {},
  paramValues = {},
  isTableOnlyEmitCurRowChange,
}) => {
  let retOptions = [];
  if (
    paramKeys.includes("formData") &&
    [-1, null, undefined].includes(paramValues["rowIdx"])
  ) {
    staticConfig.options = resOptions;
    retOptions = resOptions;
  } else if (paramKeys.includes("rowIdx") && paramValues["rowIdx"] >= 0) {
    if (
      Array.isArray(staticConfig.options) ||
      staticConfig.options === undefined
    ) {
      if (isTableOnlyEmitCurRowChange) {
        const orgDefaultValue = Array.isArray(staticConfig.options)
          ? cloneDeep(staticConfig.options)
          : [];
        const optObj =
          orgDefaultValue.length === 0
            ? resOptions
            : {
                defaultValue: orgDefaultValue,
                [paramValues["rowIdx"]]: resOptions,
              };
        staticConfig.options = optObj;
        retOptions = optObj;
      } else {
        staticConfig.options = resOptions;
        retOptions = resOptions;
      }
    } else {
      if (isTableOnlyEmitCurRowChange) {
        const optionsObj = cloneDeep(staticConfig.options);
        optionsObj[paramValues["rowIdx"]] = resOptions;
        staticConfig.options = optionsObj;
        retOptions = optionsObj;
      } else {
        staticConfig.options = resOptions;
        retOptions = resOptions;
      }
    }
  }
  return retOptions;
};

/**
 * 获取下拉的options
 * 表单 paramKeys=["metaItem","metaItemList","commonAttr","formData",]
 * 表格 paramKeys=["metaItem","metaItemList","commonAttr","rowIdx","colIdx","rowData","tableBodyData"]
 */
export const getDynmicSelectOptions = async function ({
  optionsConfigAlias, //必传
  staticConfig, //必传
  paramKeys = [
    "metaItem",
    "metaItemList",
    "commonAttr",
    "formData",
    "rowIdx",
    "colIdx",
    "rowData",
    "tableBodyData",
  ],
  paramValues = {},
  isTableOnlyEmitCurRowChange = true,
  optionsTreeConfig = {
    isInvertTree: false,
    lazy: false,
  },
  crudServiceVmTemplateConfig,
}) {
  // 请求之前需要的操作,如: 省-市-区, 切换省的时候 需要把原本 区 里面的options 和 值 都清空
  if (optionsConfigAlias?.beforeDynmicReqFunc) {
    const doBeforeDynmicReq = new Function(
      "configObj",
      optionsConfigAlias.beforeDynmicReqFunc
    );
    doBeforeDynmicReq(paramValues);
  }
  // 是否禁止请求,如: 省-市-区, 切换省的时候 区 下拉这里不需要执行请求
  if (optionsConfigAlias?.canSendDynmicReqFunc) {
    const canSendDynmicReq = new Function(
      "configObj",
      optionsConfigAlias.canSendDynmicReqFunc
    )(paramValues);
    if (canSendDynmicReq === false) {
      return Promise.resolve({ code: 1 });
    }
  }
  /* 选项来自静态手动编码的options */
  // {"optionsConfig":{"dataFromType":"Static","options":[{"label":"是","value":true},{"label":"否","value":false}]}}
  if (optionsConfigAlias?.dataFromType === "Static") {
    // staticConfig.hasOwnProperty('options') ? this.$delete(staticConfig,"options") : null;
    let options = [];
    if (optionsConfigAlias.hasOwnProperty("optionsFunc")) {
      options = new Function("configObj", optionsConfigAlias.optionsFunc)(
        paramValues
      );
    } else {
      options = optionsConfigAlias.options;
    }
    options = getSelectOptions({
      staticConfig,
      resOptions: options,
      paramKeys,
      paramValues,
      isTableOnlyEmitCurRowChange,
    });

    if (optionsConfigAlias?.afterDynmicReqFunc) {
      const doAfterDynmicReq = new Function(
        "configObj",
        optionsConfigAlias.afterDynmicReqFunc
      );
      doAfterDynmicReq(paramValues);
    }
    /* if (optionsTreeConfig.isInvertTree && !optionsTreeConfig.lazy) {
            const treeData = treeTools.invertTree({sourceArr:options, lazy:optionsTreeConfig.lazy})
            options = treeData.result
        } */
    return Promise.resolve({ code: 0, data: { items: options } });
    // staticConfig.options = optionsConfigAlias.options
  }
  /* 选项来自 API接口、本地、VmCode、DictData ;并且需要映射好label、value */
  // {"optionsConfig":{"dataFromType":"Api","url":"/emp/role/get-list","params":{"isPaged":false},"valueKeyAlias":"id","labelKeyAlias":"name"}}
  else if (
    ["Api", "Local", "VmCode", "DictData"].includes(
      optionsConfigAlias?.dataFromType
    )
  ) {
    let res = { data: {}, items: [] };
    let isSuccessReq = false;
    let labelKeyAlias = optionsConfigAlias?.labelKeyAlias ?? "text";
    let valueKeyAlias = optionsConfigAlias?.valueKeyAlias ?? "value";
    let params = optionsConfigAlias?.params ?? {};

    if (typeof optionsConfigAlias.labelKeyAliasFunc === "string") {
      const getDynmicFunc = new Function(
        "configObj",
        optionsConfigAlias.labelKeyAliasFunc
      );
      labelKeyAlias = getDynmicFunc(paramValues);
    }
    if (typeof optionsConfigAlias.valueKeyAliasFunc === "string") {
      const getDynmicFunc = new Function(
        "configObj",
        optionsConfigAlias.valueKeyAliasFunc
      );
      valueKeyAlias = getDynmicFunc(paramValues);
    }
    if (typeof optionsConfigAlias.paramsFunc === "string") {
      const getDynmicFunc = new Function(
        "configObj",
        optionsConfigAlias.paramsFunc
      );
      params = getDynmicFunc(paramValues);
    }

    let vmTemplateConfig = {};
    if (optionsConfigAlias.hasOwnProperty("vmTemplateConfig")) {
      vmTemplateConfig = optionsConfigAlias.vmTemplateConfig;
    } else {
      const isProxyToGdSysProject =
        crudServiceVmTemplateConfig.tree?.[
          "_gdAccbuild_GdSysProject_proxyFlag"
        ] ??
        crudServiceVmTemplateConfig.table?.[
          "_gdAccbuild_GdSysProject_proxyFlag"
        ];
      if (isProxyToGdSysProject) {
        vmTemplateConfig["_gdAccbuild_GdSysProject_proxyFlag"] = true;
      }
    }
    if (optionsConfigAlias.dataFromType === "Api") {
      let url = optionsConfigAlias?.url ?? "";
      if (typeof optionsConfigAlias.urlFunc === "string") {
        const getDynmicFunc = new Function(
          "configObj",
          optionsConfigAlias.urlFunc
        );
        url = getDynmicFunc(paramValues);
      }
      //TODO:FIXME:来自API接口
      res = { code: 0, data: { items: [] } };
      /* await getListOptions(
                url,
                params
            ) */
      isSuccessReq = isSuccessReqBackend(res);
    } else if (optionsConfigAlias.dataFromType === "VmCode") {
      let vmCode = optionsConfigAlias?.vmCode ?? "";
      let moduleCode =
        optionsConfigAlias?.moduleCode ?? vmTemplateConfig.moduleCode;
      res = await globalConfig.getList({
        moduleCode,
        vmCode,
        params,
        vmTemplateConfig,
      });
      isSuccessReq = isSuccessReqBackend(res);
    } else if (optionsConfigAlias.dataFromType === "DictData") {
      let moduleCode =
        optionsConfigAlias?.moduleCode ?? vmTemplateConfig.moduleCode;
      res = await globalConfig.getList({
        moduleCode: "gd_sys",
        vmCode: "DictData",
        params,
        vmTemplateConfig,
      });
      isSuccessReq = isSuccessReqBackend(res);
    } else {
      const localDictName = optionsConfigAlias?.params?.name ?? "";
      if (localDictName) {
        res = { data: {}, items: globalConfig.store.getters.allStaticSelect[localDictName] };
        isSuccessReq = true;
      }
    }

    if (isSuccessReq) {
      //console.log(res, '返回结果')
      let items = getBackendDataItems(res).map((el) => ({
        id: el.id,
        parentId: el.parentId,
        label: el[labelKeyAlias] ?? el["name"],
        value: el[valueKeyAlias],
        data: el,
        disabled: el?.disabled ?? false,
      }));
      const getProcessedOptions = (items) => {
        if (optionsTreeConfig.isInvertTree && !optionsTreeConfig.lazy) {
          const treeData = treeTools.invertTree({
            sourceArr: items,
            lazy: optionsTreeConfig.lazy,
          });
          return treeData.result;
        } else {
          return items;
        }
      };
      let resOptions = getProcessedOptions(items);
      //拦截修改label、value
      if (typeof optionsConfigAlias.interceptChangeOptionsFunc === "string") {
        const getDynmicFunc = new Function(
          "configObj",
          optionsConfigAlias.interceptChangeOptionsFunc
        );
        const interceptOptions = getBackendDataItems(res);
        resOptions = getDynmicFunc({ ...paramValues, interceptOptions });
      }

      resOptions = getSelectOptions({
        staticConfig,
        resOptions,
        paramKeys,
        paramValues,
        isTableOnlyEmitCurRowChange,
      });

      if (optionsConfigAlias?.afterDynmicReqFunc) {
        const getDynmicFunc = new Function(
          "configObj",
          optionsConfigAlias.afterDynmicReqFunc
        );
        getDynmicFunc(paramValues);
      }
      return Promise.resolve({ code: 0, data: { items: resOptions } });
    } else {
      return Promise.resolve({ code: 1 });
    }
  }
};

/**
 * 动态设置options
 */
export default async (
  props,
  optionsTreeConfig = {
    isInvertTree: false,
    lazy: false,
  }
) => {
  ////////////////
  const crudServiceVmTemplateConfig = inject(
    "crudServiceVmTemplateConfig",
    reactive({ tree: {}, table: {} })
  );
  ///////////////
  //如果动态函数中存在 行 数据时;就表格每行都会触发
  const isRowIndependent = computed(() => {
    if (
      typeof props.metaDynmicConfig === "object" &&
      props.metaDynmicConfig.hasOwnProperty("optionsConfig")
    ) {
      const keys = Object.keys(props.metaDynmicConfig.optionsConfig);
      const dynmicKeys = keys.filter((key) => key.endsWith("Func"));
      const isRowIndependent = dynmicKeys.some((key) => {
        const isRowIndependent = ["rowIdx", "rowData"].some((el) =>
          props.metaDynmicConfig.optionsConfig[key].indexOf(el)
        );
        return isRowIndependent;
      });
      return isRowIndependent;
    } else {
      return false;
    }
  });
  const optionsConfig = computed(() => {
    if (
      typeof props.metaDynmicConfig === "object" &&
      props.metaDynmicConfig.hasOwnProperty("optionsConfig")
    ) {
      return props.metaDynmicConfig.optionsConfig;
    } else {
      return null;
    }
  });
  watch(
    optionsConfig,
    async (newVal, oldVal) => {
      if (newVal && (props.metaDynmicConfig?.optionsConfigTrigger ?? true)) {
        //没有使用 "行" 数据,则立即关闭触发标记,避免重复请求
        if (!isRowIndependent.value) {
          props.metaDynmicConfig.optionsConfigTrigger = false;
        }
        const res = await getDynmicSelectOptions({
          optionsConfigAlias: props.metaDynmicConfig.optionsConfig,
          staticConfig: props.metaItem,
          paramValues: {
            metaItem: props.metaItem,
            metaItemList: props.metaItemList,
            commonAttr: props.commonAttr,
            formData: props.formData,
            rowIdx: props.rowIdx,
            colIdx: props.colIdx,
            rowData: props.rowData,
            tableBodyData: props.tableBodyData,
          },
          optionsTreeConfig,
          crudServiceVmTemplateConfig,
        });
        props.metaItem.options = getBackendDataItems(res);
        //console.log(res, "动态获取options");
      }
    },
    { immediate: true }
  );
};
